package com.spring.wx.oauth.conntroller;

import com.alibaba.fastjson.JSONObject;
import com.spring.wx.oauth.entity.UserEntity;
import com.spring.wx.oauth.entity.WxLoginUser;
import com.spring.wx.oauth.service.UserService;
import com.spring.wx.oauth.service.WxLoginUserService;
import com.spring.wx.oauth.utils.HttpClientUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

/**
 * Copyright: yueyong (c) 2022
 *
 * @author he.shaorong
 * @version 1.0
 * @date 2022/6/26
 */
@RestController
public class ScanQRCodeController {

    private String WX_OPEN_APP_ID = "wxd13c593e82ed7df9";
    private String WX_OPEN_REDIRECT_URL = "http://wx.yyysmart.com/smart-admin-api/callback";
    private String WX_OPEN_APP_SECRET = "587e4cb63bd94ba5a64bbbcb71d94cd7";

    @Autowired
    private WxLoginUserService wxLoginUserService;

    @GetMapping("getLoginParam")
    @ResponseBody
    public Map<String, Object> genQrConnect() {
        try {
            Map<String, Object> map = new HashMap<>();
            map.put("appid", WX_OPEN_APP_ID);
            map.put("scope","snsapi_login");
            String wxOpenRedirectUrl = WX_OPEN_REDIRECT_URL;
            wxOpenRedirectUrl = URLEncoder.encode(wxOpenRedirectUrl, "utf-8");
            map.put("redirect_uri",wxOpenRedirectUrl);
            String state = System.currentTimeMillis()+"";
            map.put("state", state);
            map.put("url", "https://open.weixin.qq.com/connect/qrconnect?appid="+ WX_OPEN_APP_ID
                    + "&redirect_uri="+ wxOpenRedirectUrl
                    + "&response_type=code&scope=snsapi_login&"
                     + "state=" + state +"#wechat_redirect");
            return map;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            return null;
        }
    }

    @GetMapping("/smart-admin-api/callback")
    public String callback(String code, String state) {
        //获取临时票据 code
        System.out.println("callback -- code:{}"+ code + " state:{}"+ state);

        // 组装获取accessToken的url
        String accessTokenUrl = getAccessTokenUrl(code);

        // httpclient请求获取accesstokenInfo
        try {
            //从返回字符串获取两个值 openid和access_token
            JSONObject jsonObject = HttpClientUtils.doGet(accessTokenUrl);
            String access_token = jsonObject.getString("access_token");
            String openid = jsonObject.getString("openid");


            //拿到用户信息
            JSONObject jsonObjectUser = HttpClientUtils.doGet(getUserInfoUrl(access_token, openid));
            System.out.println(jsonObjectUser);

            //根据openid判断数据库是否存在微信用户信息
            //todo 落库state
            WxLoginUser wxLoginUser = wxLoginUserService.getOpenid(openid);
            if (wxLoginUser == null) {
                wxLoginUser = buildWxLoginUser(jsonObjectUser);
                wxLoginUser.setState(state);
                wxLoginUserService.insert(wxLoginUser);
            } else {
                wxLoginUser.setCity(jsonObjectUser.getString("city"));
                wxLoginUser.setImage(jsonObjectUser.getString("headimgurl"));
                wxLoginUser.setNickname(jsonObjectUser.getString("nickname"));
                wxLoginUser.setSex(jsonObjectUser.getInteger("sex"));
                wxLoginUser.setState(state);
                wxLoginUserService.update(wxLoginUser);
            }
            return "SUCCESS";
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 使用code、appid、appscrect换取access_token
     *
     * @param code
     * @return
     */
    private String getAccessTokenUrl(String code) {
        StringBuffer baseAccessTokenUrl = new StringBuffer()
                .append("https://api.weixin.qq.com/sns/oauth2/access_token")
                .append("?appid=%s")
                .append("&secret=%s")
                .append("&code=%s")
                .append("&grant_type=authorization_code");
        String accessTokenUrl = String.format(baseAccessTokenUrl.toString(),
                WX_OPEN_APP_ID,
                WX_OPEN_APP_SECRET,
                code);
        return accessTokenUrl;
    }

    /**
     * 通过openid和access_token得到用户信息
     *
     * @param access_token
     * @param openid
     * @return
     */
    private String getUserInfoUrl(String access_token, String openid) {
        String baseUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo" +
                "?access_token=%s" +
                "&openid=%s";
        String userInfoUrl = String.format(baseUserInfoUrl, access_token, openid);
        return userInfoUrl;
    }

    private WxLoginUser buildWxLoginUser(JSONObject jsonObjectUser) {
        WxLoginUser wxLoginUser = new WxLoginUser() ;
        wxLoginUser.setOpenid(jsonObjectUser.getString("openid"));
        wxLoginUser.setCity(jsonObjectUser.getString("city"));
        wxLoginUser.setImage(jsonObjectUser.getString("headimgurl"));
        wxLoginUser.setNickname(jsonObjectUser.getString("nickname"));
        wxLoginUser.setSex(jsonObjectUser.getInteger("sex"));

        return wxLoginUser;
    }
}
